package adm


import (
	"encoding/xml"
	"fmt"
	"bytes"
	"git.oschina.net/janpoem/go-agi"
)

type XmlConfig struct {
	XMLName     xml.Name    `xml:"databases"`
	Dbs         []XmlDb     `xml:"database"`
}

type XmlDb struct {
	XMLName     xml.Name    `xml:"database"`
	DSN         string      `xml:"dsn,attr"`
	Name        string      `xml:"name,attr"`
	Host        string      `xml:"host"`
	Port        int         `xml:"port"`
	Db          string      `xml:"db"`
	User        string      `xml:"user"`
	Password    string      `xml:"password"`
	MaxConn     int         `xml:"maxConn"`
	MaxIdle     int         `xml:"maxIdle"`
	Charset     string      `xml:"charset"`
	Options     []XmlDbOps  `xml:"option"`
}

type XmlDbOps struct {
	XMLName     xml.Name    `xml:"option"`
	Name        string      `xml:"name,attr"`
	Value       string      `xml:"value,attr"`
}

var dbConfigs = make(map[string]*XmlDb)

func LoadConf(path string) {
	data, err := agi.ReadFileByte(path)
	if err != nil {
		fmt.Println(err)
	} else {
		config := XmlConfig{}
		err = xml.Unmarshal(data, &config)
		for i, len := 0, len(config.Dbs); i < len; i++ {
			addDbConf(&config.Dbs[i])
		}
	}
}

func addDbConf(db *XmlDb) {
	_, exists := dbConfigs[db.Name]
	if !exists {
		dbConfigs[db.Name] = db
	}
}

func GetConf(name string) (*XmlDb) {
	item, exists := dbConfigs[name]
	if exists {
		return item
	}
	return nil
}

func (this *XmlDb) GetPort() (int) {
	port := this.Port
	if port <= 0 {
		port = 3306
	}
	return port
}

func (this *XmlDb) GetCharset() (string) {
	if len(this.Charset) <= 0 {
		return "utf8"
	}
	return this.Charset
}

func (this *XmlDb) GetOpsStr() (string) {
	i, l := 0, len(this.Options)
	buffer := bytes.NewBufferString("charset=" + this.GetCharset())
	for ; i < l; i++ {
		buffer.WriteString("&")
		buffer.WriteString(this.Options[i].Name + "=" + this.Options[i].Value)
	}
	return buffer.String()
}

func (this *XmlDb) GetConnDSN() (string) {
	return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?%s", this.User, this.Password, this.Host, this.GetPort(), this.Db, this.GetOpsStr())
}
